package com.zyj.core.handler.statementhandler;

import com.zyj.core.config.Configuration;
import com.zyj.core.config.MappedStatement;
import com.zyj.core.handler.parameterhandler.ParameterHandler;
import com.zyj.core.handler.resultsethandler.ResultSetHandler;
import com.zyj.core.sqlsource.BoundSql;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;

/**
 * 默认的StatementHandler
 */
public class PreparedStatementHandler implements StatementHandler {

    // Statement处理器要持有参数处理器
    private ParameterHandler parameterHandler;
    // Statement处理器要持有结果集处理器
    private ResultSetHandler resultSetHandler;

    /**
     * 在构造方法中根据配置文件指定参数处理器和结果集处理器
     *
     * @param configuration
     */
    public PreparedStatementHandler(Configuration configuration) {
        // 根据配置文件获取参数处理器
        this.parameterHandler = configuration.newParameterHandler();
        // 根据配置文件获取结果集处理器
        this.resultSetHandler = configuration.newResultSetHandler();
    }

    /**
     * 根据连接对象获取Statement对象
     *
     * @param connection
     * @param sql
     * @return
     * @throws Exception
     */
    @Override
    public Statement prepare(Connection connection, String sql) throws Exception {
        // 此处返回PreparedStatement对象
        return connection.prepareStatement(sql);
    }

    /**
     * 给sql设置参数值
     *
     * @param statement
     * @param param
     * @param boundSql
     * @throws Exception
     */
    @Override
    public void parameterize(Statement statement, Object param, BoundSql boundSql) throws Exception {
        PreparedStatement preparedStatement = (PreparedStatement) statement;
        // 真正进行参数处理的是ParameterHandler
        parameterHandler.setPatameter(preparedStatement, param, boundSql);
    }

    /**
     * 调用preparedStatement对象来执行数据库查询
     *
     * @param statement       预编译statement
     * @param mappedStatement
     * @param <T>
     * @return
     * @throws Exception
     */
    @Override
    public <T> List<T> query(Statement statement, MappedStatement mappedStatement) throws Exception {
        PreparedStatement preparedStatement = (PreparedStatement) statement;

        // 调用preparedStatement对象来执行数据库查询，得到结果集
        ResultSet rs = preparedStatement.executeQuery();

        // 根据mappedStatement中封装的resultType来处理结果集
        // 调用结果集处理器来处理查询结果
        return resultSetHandler.handleResult(statement, rs, mappedStatement);
    }
}
